import { createRouter, createWebHashHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
import { useAuthStore } from '@/stores/modules/auth.ts'
import { useMenuStore } from '@/stores/modules/menu.ts'
import NProgress from 'nprogress'
import { systemRoutes, systemAuthRoutes } from './modules/system'
import menuTool from './menuRoute'
import config from '@/config'

// 生成带时间戳的日志前缀
const getLogPrefix = () => `[${new Date().toISOString().slice(11, 23)}][路由守卫]`

// 扁平化本地静态路由
export const staticRoutes = menuTool.getFlatStaticRoutesList(menuTool.staticRoutes())
console.log(`${getLogPrefix()} 初始化静态路由数量:`, staticRoutes.length)

// 引入 views 文件夹下所有 vue 文件，排除components文件夹
const modules = import.meta.glob(['@/views/**/*.vue', '!@/views/**/components'])
console.log(`${getLogPrefix()} 视图模块加载数量:`, Object.keys(modules).length)

const router = createRouter({
    history: createWebHashHistory(),
    routes: [...systemRoutes, ...systemAuthRoutes],
    strict: false,
    scrollBehavior: () => ({ left: 0, top: 0 })
})

// 判断是否已加载过动态/静态路由
let isGetRouter = false
console.log(`${getLogPrefix()} 初始化路由完成，isGetRouter初始值:`, isGetRouter)

// 路由拦截 beforeEach
router.beforeEach((to, from, next) => {
    const startTime = performance.now() // 记录开始时间
    const authStore = useAuthStore()
    const logPrefix = getLogPrefix()

    console.log(`${logPrefix} 开始导航 | 目标: ${to.path} | 来源: ${from.path || '初始页面'}`)

    // NProgress
    NProgress.start()
    console.log(`${logPrefix} NProgress已启动`)

    // 动态设置标题
    const pageTitle = to.meta.title ? `${to.meta.title} - ${config.APP_NAME}` : `${config.APP_NAME}`
    document.title = pageTitle
    console.log(`${logPrefix} 页面标题已设置为:`, pageTitle)

    // 判断访问的是静态auth路由
    const isAuthRoute = systemAuthRoutes.some(
        (authRoute) => authRoute.path.toLocaleLowerCase() === to.path.toLocaleLowerCase()
    )

    if (isAuthRoute) {
        console.log(`${logPrefix} 检测到访问认证路由: ${to.path}`)

        if (authStore.accessToken) {
            console.log(`${logPrefix} 已登录状态，阻止访问认证路由，停留当前页: ${from.path}`)
            NProgress.done()
            return next(from.fullPath)
        } else {
            console.log(`${logPrefix} 未登录状态，准备重置路由`)
            resetRouter()
            isGetRouter = false
            console.log(`${logPrefix} 路由已重置，允许访问认证路由`)
            NProgress.done()
            return next()
        }
    }

    // 判断是否有 Token
    if (!authStore.accessToken) {
        console.log(`${logPrefix} 无访问令牌，重定向到登录页`)
        NProgress.done()
        return next({ path: '/login', replace: true })
    }

    // 添加静态/动态路由
    if (!isGetRouter) {
        console.log(`${logPrefix} 路由未初始化，开始加载静态/动态路由 (耗时监测点)`)
        const routeLoadStartTime = performance.now()

        // 添加静态路由
        console.log(`${logPrefix} 开始添加静态路由，共 ${staticRoutes.length} 条`)
        staticRoutes.forEach((item, index) => {
            try {
                if (item.meta?.isFull) {
                    router.addRoute(item as unknown as RouteRecordRaw)
                } else {
                    router.addRoute('layout', item as unknown as RouteRecordRaw)
                }
                console.log(
                    `${logPrefix} 静态路由添加成功 [${index + 1}/${staticRoutes.length}]: ${item.path}`
                )
            } catch (error) {
                console.error(
                    `${logPrefix} 静态路由添加失败 [${index + 1}/${staticRoutes.length}]: ${item.path}`,
                    error
                )
            }
        })

        // 添加动态路由
        const menuStore = useMenuStore()
        const apiMenu = menuTool.getFlatMenuList(menuStore.menu)
        console.log(`${logPrefix} 开始添加动态路由，共 ${apiMenu.length} 条`)

        apiMenu.forEach((item, index) => {
            const routeName = item.name || item.path
            try {
                // 移除children避免嵌套问题
                if (item.children) {
                    delete item.children
                    console.log(`${logPrefix} 动态路由[${index + 1}]移除children: ${routeName}`)
                }

                // 处理组件加载
                if (item.component && typeof item.component === 'string') {
                    const componentPath =
                        item.viewType == 1
                            ? `/src/views/${item.component}.vue`
                            : '/src/views/maintenance/devTools/render/index.vue'

                    if (modules[componentPath]) {
                        item.component = modules[componentPath]
                        console.log(
                            `${logPrefix} 动态路由[${index + 1}]组件加载成功: ${componentPath}`
                        )
                    } else {
                        console.error(
                            `${logPrefix} 动态路由[${index + 1}]组件不存在: ${componentPath}`
                        )
                    }
                }

                // 添加路由
                if (item.meta?.fullpage) {
                    router.addRoute(item as unknown as RouteRecordRaw)
                } else {
                    router.addRoute('layout', item as unknown as RouteRecordRaw)
                }
                console.log(
                    `${logPrefix} 动态路由添加成功 [${index + 1}/${apiMenu.length}]: ${routeName}`
                )
            } catch (error) {
                console.error(
                    `${logPrefix} 动态路由添加失败 [${index + 1}/${apiMenu.length}]: ${routeName}`,
                    error
                )
            }
        })

        isGetRouter = true
        const routeLoadEndTime = performance.now()
        console.log(
            `${logPrefix} 静态/动态路由加载完成 | 耗时: ${(routeLoadEndTime - routeLoadStartTime).toFixed(2)}ms`
        )
        console.log(`${logPrefix} 重新导航到目标页: ${to.path}`)
        return next({ ...to, replace: true })
    }

    // 正常访问页面
    const endTime = performance.now()
    console.log(
        `${logPrefix} 导航验证通过 | 总耗时: ${(endTime - startTime).toFixed(2)}ms | 进入页面: ${to.path}`
    )
    next()
})

// 重置路由
export const resetRouter = () => {
    const logPrefix = getLogPrefix()
    console.log(`${logPrefix} 开始重置路由`)
    const resetStartTime = performance.now()

    const menuStore = useMenuStore()
    const apiMenu = menuTool.getFlatMenuList(menuStore.menu)
    console.log(`${logPrefix} 待移除的动态路由数量: ${apiMenu.length}`)

    apiMenu.forEach((route, index) => {
        const { name } = route
        if (name) {
            if (router.hasRoute(name)) {
                router.removeRoute(name)
                console.log(`${logPrefix} 移除路由 [${index + 1}/${apiMenu.length}]: ${name}`)
            } else {
                console.log(
                    `${logPrefix} 路由不存在，跳过移除 [${index + 1}/${apiMenu.length}]: ${name}`
                )
            }
        } else {
            console.log(`${logPrefix} 路由无名称，无法移除 [${index + 1}/${apiMenu.length}]`)
        }
    })

    const resetEndTime = performance.now()
    console.log(`${logPrefix} 路由重置完成 | 耗时: ${(resetEndTime - resetStartTime).toFixed(2)}ms`)
}

// 路由跳转错误
router.onError((error) => {
    const logPrefix = getLogPrefix()
    NProgress.done()
    console.error(`${logPrefix} 路由跳转错误:`, error)

    const fetchResourcesErrors = [
        'Failed to fetch dynamically imported module',
        'Importing a module script failed'
    ]

    if (error?.message && fetchResourcesErrors.some((item) => error.message.includes(item))) {
        console.error(`${logPrefix} 检测到资源加载失败，准备刷新页面`)
        window.location.reload()
        return
    }

    console.warn(`${logPrefix} 路由错误详情:`, error.message)
})

// 路由跳转结束
router.afterEach((to, from) => {
    const logPrefix = getLogPrefix()
    console.log(`${logPrefix} 导航完成 | 页面: ${to.path} | 从 ${from.path || '初始页面'} 跳转`)
    NProgress.done()
})

export default router
